package com.runvp.common.util.enc;

import com.runvp.common.hex.HexConvert;

import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

public class AESGCMDecryptionn {
    public static void main(String[] args) throws Exception {
        String ivHex = HexConvert.str2HexStr("98BPRR4Wve41");
        String keyHex = HexConvert.str2HexStr("BMrcujdO0XDjvOOa");
        ivHex = "393842505252345776653431";
        keyHex = "424d7263756a644f3058446a764f4f61";
        String tagHex = HexStringToASCII.hexToAscii("7130C4C92F60B7EB4D565B1DDFC2559E");
        String encryptedDataHex = HexStringToASCII.hexToAscii("6BE3153AFC79025ACDF03CB38D988927BBF1DB4FCE387729CB19AB13FEC136");

        byte[] encryptedData = HexStringToASCII.hexToAsciiByte("6BE3153AFC79025ACDF03CB38D988927BBF1DB4FCE387729CB19AB13FEC136");
        byte[] iv = fromHexString(ivHex);
        byte[] keyBytes = fromHexString(keyHex);
        byte[] tag = HexStringToASCII.hexToAsciiByte("7130C4C92F60B7EB4D565B1DDFC2559E");

        SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
        GCMParameterSpec spec = new GCMParameterSpec(128, iv);

        Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, spec);
        // 添加Tag进行验证
        cipher.updateAAD(tag);
        // 实际解密操作
        byte[] actualDecryptedData = cipher.doFinal(encryptedData);

        System.out.println("Decrypted Data: " + new String(actualDecryptedData, StandardCharsets.UTF_8));
    }

    private static byte[] fromHexString(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.trim();
        byte[] bytes = new byte[hexString.length() / 2];
        for (int i = 0; i < hexString.length(); i += 2) {
            bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4)
                    + Character.digit(hexString.charAt(i+1), 16));
        }
        return bytes;
    }
}